<?php

class BaseController
{
    protected $tableName;
    protected $pk;

    protected $conn;

    public function __construct()
    {
        $this->conn = DB::getConnector();
    }

    protected function getArrayDataFromResult($result)
    {
        $dataArray = array();
        while ($row = $result->fetch_assoc()) {
            array_push($dataArray, $row);
        }
        return $dataArray;
    }

    protected function getSingleDataFromResult($result) {
        if( mysqli_num_rows($result) < 1){
            return [];
        }else{
            return $result->fetch_assoc();
        }
    }

    protected function getValueStr($field, $value) {
        $valueStr = $value;
        if($value === null) {
            $valueStr = "null";
        }
        else {
            if(strpos($field["Type"], "varchar") !== false || strpos($field["Type"], "text") !== false) {
                $valueStr = "'" . $valueStr . "'";
            }
            else if(strpos($field["Type"], "date") !== false) {
                $valueStr = "'" . $valueStr . "'";
            }
        }
        return $valueStr;
    }

    protected function getFields() {
        $fields = array();
        $tmpResult = $this->conn->query("desc $this->tableName;");
        while ($row = $tmpResult->fetch_assoc()) {
            array_push($fields, $row);
        }
        return $fields;
    }

    protected function getFieldsMap() {
        $fieldsMap = array();
        $tmpResult = $this->conn->query("desc $this->tableName;");
        while ($row = $tmpResult->fetch_assoc()) {
            $fieldsMap[$row["Field"]] = $row;
        }
        return $fieldsMap;
    }

    protected function getIdStr($id) {
        // 因为有int和varchar两种id，因此这里需要区别
        $fieldMap = $this->getFieldsMap();
        $pkType = $fieldMap[$this->pk]['Type'];
        if (strpos($pkType, "varchar") !== false) {
            // varchar类型
            return '"'. $id .'"';
        }
        else {
            return $id;
        }
    }

    public function getNewRecord($obj) {
        // 查看是否传入主键，如果没有传入则是自增主键，通过主键查询该数据
        $id = array_key_exists($this->pk, $obj) ? $obj[$this->pk] : $this->conn->insert_id;
        $getRes = $this->get($id);
        return $getRes['data'];
    }

    public function get($id)
    {
        $idStr = $this->getIdStr($id);
        $sql = "select * from $this->tableName where $this->pk=$idStr";
        $result = $this->conn->query($sql);
        $data = $this->getSingleDataFromResult($result);
        if (empty($data)) {
            return ReturnHelper::failed([], "无数据或id有误", 404);
        }
        else {
            return ReturnHelper::success($data, "数据请求成功");
        }
    }

    public function getList()
    {
        $sql = "select * from $this->tableName";
        $result = $this->conn->query($sql);
        $data = $this->getArrayDataFromResult($result);
        return ReturnHelper::success($data, "数据请求成功");
    }

    protected function judge($result) {
        if ($result && mysqli_affected_rows($this->conn) > 0) {
            return true;
        }
        else {
            return false;
        }
    }

    public function delete($id) {
        $idStr = $this->getIdStr($id);
        $sql = "delete from $this->tableName where $this->pk=$idStr";
        $result = $this->conn->query($sql);
        $flag = $this->judge($result);
        if ($flag) {
            return ReturnHelper::success([], "数据`$id`删除成功");
        }
        else {
            return ReturnHelper::failed([], "数据`$id`删除失败");
        }
    }

    public function post($obj)
    {
        $sql = "INSERT INTO $this->tableName VALUES(";
        $fields = $this->getFields();
        for ($i = 0; $i < count($fields); $i++) {
            if($i !== 0) {
                $sql .= ", ";
            }
            $field = $fields[$i];
            $fieldName = $field['Field'];
            $value = array_key_exists($fieldName, $obj)? $obj[$fieldName] : null;
            $valueStr = $this->getValueStr($field, $value);
            $sql .= $valueStr;
        }
        $sql .= ");";
        $result = $this->conn->query($sql);
        $flag = $this->judge($result);

        // 新增成功
        if ($flag) {
            // 查看是否传入主键，如果没有传入则是自增主键，通过主键查询改数据
            $id = array_key_exists($this->pk, $obj) ? $obj[$this->pk] : $this->conn->insert_id;
            $getRes = $this->get($id);
            return ReturnHelper::success($getRes['data'], "数据新增成功");
        }
        else {
            return ReturnHelper::failed([], "数据新增失败：" . $this->conn->error);
        }
    }

    public function update($id, $obj)
    {
        $idStr = $this->getIdStr($id);
        $sql = "UPDATE $this->tableName SET ";
        $isFirst = true;
        $fieldsMap = $this->getFieldsMap();
        foreach($obj as $fieldName=>$valueStr) {
            if($isFirst !== true) {
                $sql .= ", ";
            }
            else {
                $isFirst = false;
            }
            $field = $fieldsMap[$fieldName];
            $sql .= $fieldName . " = ";
            $value = $obj[$fieldName];
            $valueStr = $this->getValueStr($field, $value);
            $sql .= $valueStr;
        }
        $sql .= " WHERE $this->pk = ". $idStr .";";
//        echo $sql;
        $result = $this->conn->query($sql);
        $flag = $this->judge($result);
        if ($flag) {
            return ReturnHelper::success($this->get($id)['data'], "数据修改成功");
        }
        else {
            if ($result) {
                return ReturnHelper::success($this->get($id)['data'], "数据前后没有发生改变");
            }
            return ReturnHelper::failed([], "数据修改失败："  . $this->conn->error);
        }
    }

}